feat(http): dashboard + brand-feeds reads use resolver (#4159 Stage 1.3)#4303
Merged
feat(http): dashboard + brand-feeds reads use resolver (#4159 Stage 1.3)#4303
Conversation
Migrates four read sites: - GET /api/members: batched resolver lookup; brand-primary keyed by org_id rather than per-row column. - GET /api/members/carousel: same batched pattern. - GET /api/members/:slug: single-org resolver. - routes/brand-feeds.ts ownership check: replaces the member_profiles query in the owned-domains union with the resolver. orgDomains query unchanged (still walks all verified rows). The list endpoints are the first real users of the batched resolver variant getBrandPrimaryDomainsForOrgs from PR #4299. Behavior unchanged post-Stage-0 — brand-primary now keys on organization_domains.is_primary canonically with member_profiles fallback for orgs the backfill missed. 97 tests pass across the 6 affected test files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Tighten the batched-resolver comment in /api/members (was 'three queries', should be 'constant number'; resolver itself can do 1-2). - Trim the brand-feeds ownership-gate comment. - TODO(#4159) noting the pre-existing verified-filter gap on the ownership gate. Set-equivalent to before this PR; worth fixing in Stage 2 when the column drops and the gate logic gets revisited. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stage 1.3 of #4159. Four more read sites migrated, including the first real users of the batched resolver variant.
GET /api/members(server/src/http.ts:8300)getBrandPrimaryDomainsForOrgs(batch)GET /api/members/carousel(http.ts:8351)getBrandPrimaryDomainsForOrgs(batch)GET /api/members/:slug(http.ts:8385)getBrandPrimaryDomain(single)routes/brand-feeds.tsownership checkgetBrandPrimaryDomain(single)Why batching matters here
The
/api/membersand/api/members/carouselendpoints fan out across N profiles. Pre-migration: pulledprimary_brand_domainoff each profile (zero queries). Post-migration: ONE batched query for all primaries viagetBrandPrimaryDomainsForOrgs(orgIds). Same constant query count regardless of N.This is the use case the batch variant was designed for. After PR #4299 added it but no callers used it.
brand-feeds ownership check
The endpoint validates that the caller's org owns the brand domain they're trying to edit. Pre-migration: did a UNION of
organization_domains+member_profiles.primary_brand_domain. Post-migration: keeps theorganization_domainswalk (covers all verified rows, not just primary) + the resolver call (which provides the brand-primary fallback for orgs Stage 0 missed). Same effective set, simpler write path.Test plan
What's left in Stage 1
services/brand-property-parse.ts(4) +services/brand-identity.ts(6) — the brand-claim writer mostly write-sideservices/announcement-drafter.ts(1) +routes/registry-api.ts(1)addie/jobs/profile-completion-nudge.ts(5) +addie/jobs/announcement-trigger.ts(8)addie/mcp/member-tools.ts(1) +addie/mcp/brand-property-tools.ts(1)routes/si-chat.ts(1) +routes/referrals.ts(2)member-profiles.tsGET-resolution + cosmetic logo (5) — Stage 2 with column dropdb/organization-db.ts(1) — JOIN-based, may stay🤖 Generated with Claude Code